package com.jeesite.common.shiro.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeesite.common.entity.Extend;
import com.jeesite.common.pojo.UsernameVerificationCodeToken;
import com.jeesite.common.pojo.WxHttpServletRequest;
import com.jeesite.common.shiro.realm.UsernameVerificationCodeRealm;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.UserService;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.Assert;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName UsernameVerificationCodeFilter
 * @Description 用户名验证码
 * @Author Spencer Zhang
 * @Date 2025/2/15 21:01
 */
@Slf4j
public class UsernameVerificationCodeFilter extends BasicHttpAuthenticationFilter {

    @Setter
    private UsernameVerificationCodeRealm usernameVerificationCodeRealm; // 安全认证类

    private UserService userService;

    private String getRequestBody(ServletRequest request) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        BufferedReader reader = request.getReader();
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        return stringBuilder.toString();
    }

    public UserService getUserService() {
        if (userService == null) {
            userService = SpringUtils.getBean(UserService.class);
        }
        return userService;
    }
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        try {
            Map<String, String[]> params = new HashMap<>();
            params.putAll(request.getParameterMap());
            String json = getRequestBody(request);
            Assert.notNull(json, "缺少参数");
            JSONObject jsonObject = JSON.parseObject(json);
            String username = jsonObject.get("username").toString();
            String verificationCode = jsonObject.get("code").toString();
            getUserService();
            //处理用户
            User u = new User();
            u.setLoginCode(username);
            User user = userService.getByLoginCode(u);
            Assert.notNull(user, "未找到用户信息");

            Extend extend = user.getExtend();
            Assert.notNull(extend, "未找到验证信息");
            String code = extend.getExtendS1();
            Assert.notNull(code, "未发送验证码");
            Date date = extend.getExtendD1();
            Assert.notNull(date, "未发送验证码");
            Date now = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.MINUTE, 10);
            if (now.after(calendar.getTime())) {
                throw new Exception("验证码已超时,请重新获取");
            } else {
                if (verificationCode.toUpperCase().equals(code.toUpperCase())) {
                    params.put("username", new String[]{username});
                    params.put("password", new String[]{verificationCode});
                    request = new WxHttpServletRequest((HttpServletRequest) request, params);
                    return executeLogin(request, response);
                } else {
                    throw new Exception("验证码错误");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            request.setAttribute("message", e.getMessage());
        }

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");

        try (PrintWriter out = response.getWriter()) {
            String message = request.getAttribute("message").toString();
//            Session session = UserUtils.getSession();
            StringBuilder sb = new StringBuilder("{\"result\": \"false\"");
            sb.append(",\"message\":\"" + (message == null ? "登录失败" : message) + "\"}");
            out.print(sb);
            out.flush();
        } catch (IOException ioException) {
            log.error(ioException.getMessage());
        }
        return false;
    }

    /**
     * 创建登录授权令牌
     */
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        Map<String, String[]> map = request.getParameterMap();
        String phone = map.get("username")[0];
        String pwd = map.get("password")[0];
        return new UsernameVerificationCodeToken(phone, pwd, "verificationCode");
    }

    /**
     * 登录成功调用事件
     */
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        WebUtils.issueRedirect(request, response, "/api/web/user/check/verification/code", null, true);
        return false;
    }

}